var path = require('path');
var sio = require('socket.io');

var route_uploadsingle = require('./routes/uploadsingle');
var route_executecmd = require('./routes/executecmd');

function Utf8ArrayToStr(array) {
    var out, i, len, c;
    var char2, char3;

    out = "";
    len = array.length;
    i = 0;
    while (i < len) {
        c = array[i++];
        switch (c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
            case 12: case 13:
                // 110x xxxx 10xx xxxx
                char2 = array[i++];
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx 10xx xxxx 10xx xxxx
                char2 = array[i++];
                char3 = array[i++];
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }

    return out;
}

// 将外部传入的http对象、express对象和这里创建的socket.io对象建立关联
var socketio = function (httpServer, app) {
    var io = sio(httpServer);

    // 初始化socket.io的事件监听器
    io.on('connection', function (socket) {
        console.log('a user connected');

        socket.on('disconnect', function () {
            console.log('user disconnected');
        });

        // 如果服务端收到了chat message事件，将收到的内容原样传回给客户端（实现聊天室，对本项目无用）
        socket.on('chat message', function (msg) {
            console.log('message: ' + msg);

            io.emit('chat message', msg);
        });

        // 收到的客户端发送过来的请求，解析一下请求，转交给具体的路由处理，并实时将处理进度推送给客户端
        socket.on('add request', function (msg) {
            console.log('add request: ' + msg);
            var obj = JSON.parse(msg);
            var req = {
                body: {
                    // uploadsingle
                    pkgname:obj.pkgname,
                    version:obj.version,
                    pyver:obj.pyver,
                    abiver:obj.abiver,
                    osver:obj.osver,
                    repo:obj.repo,
                    cmd:obj.cmd,
                    pip:obj.pip
                }
            };
            var act = obj.action;
            var routeObj = null;
            if (act == '/uploadsingle') {
                routeObj = route_uploadsingle;
            } else if (act == '/executecmd') {
                routeObj = route_executecmd;
            }
            if (routeObj != null) {
                // 之前实现的是向所有客户端推送消息，现在改成了只向指定的客户端推送，而且只在连接上了之后才会推送
                routeObj.process_async(req, function (data) {
                    // io.emit('chat message', Utf8ArrayToStr(data));
                    if (io.sockets.connected[socket.id]) {
                        if (data instanceof Buffer) {
                            io.sockets.connected[socket.id].emit('chat message', Utf8ArrayToStr(data));
                        } else {
                            console.log('type of data: ' + typeof(data));
                            io.sockets.connected[socket.id].emit('chat message', data);
                        }
                    }
                }, function (data) {
                    // io.emit('error message', Utf8ArrayToStr(data));
                    if (io.sockets.connected[socket.id]) {
                        io.sockets.connected[socket.id].emit('error message', Utf8ArrayToStr(data));
                    }
                });
            }

        });

    });

    // 给express对象绑定路径，实现一个简单的聊天室页面（对本项目无用）
    app.get('/chat/', function (req, res) {
        res.sendFile(path.join(__dirname, 'chat.html'));
    });

    // 将socket.io对象附加到express对象上，便于后续在外部向socket.io推送数据
    app.set('io', io);
}

module.exports = socketio;
